﻿using CIS.DB;
using CIS.Web.Common;
using CIS.Web.Models;
using CIS.Web.Properties;
using System;
using System.Data.Entity;
using System.Linq;
using System.Linq.Dynamic;
using System.Threading.Tasks;
using System.Web.Mvc;

namespace CIS.Web.Controllers
{
	[RoutePrefix("ConferenceUserMaster")]
	public class ConferenceUserMasterController : BaseDbController
	{
		[Route("Index/{ConferenceId}")]
		public async Task<ActionResult> Index(string conferenceId)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", conferenceId);

			var conferenceMaster = await DbContext.ConferenceMaster.AsNoTracking()
					.FirstOrDefaultAsync(x => x.Status == ConstValues.Status.正常 &&
						x.ID == conferenceId);

			ViewBag.ConferenceId = conferenceId;
			ViewBag.ConferenceName = conferenceMaster.ConferenceName;
			ViewBag.ControllerName = Resources.ConferenceUserMaster;
			ViewBag.Language = conferenceMaster.IsInternational ? ConstValues.Language.En : ConstValues.Language.Cn;

			var model = new ConferenceUserMasterModel();
			model.ConferenceId = conferenceId;
			LoginUser.ConferenceFunctionIdList = Utility.GetConferenceFunctionIdList(conferenceId);
			return View(model);
		}

		public async Task<JsonCamelCaseResult> GetData(int? page, int? rows, string sort, string order, ConferenceUserMasterModel model)
		{
			int take = rows ?? ConstValues.DefaultGridRows;
			int skip = ((page ?? 1) - 1) * take;

			var sql = from user in DbContext.ViewConferenceRoleAction.AsNoTracking().Where(x => x.ConferenceID == model.ConferenceId)
				  .GroupBy(x => new
				  {
					  x.UserID,
				  })
				  .Select(e => new
				  {
					  UserID = e.Key.UserID,
				  })
				  join userInfo in DbContext.SysUserMaster.AsNoTracking().Where(x => x.Status == ConstValues.Status.正常)
					on user.UserID equals userInfo.ID into userInfos
				  from userInfo in userInfos.DefaultIfEmpty()
				  join callInfo in DbContext.CallMaster.AsNoTracking()
				    on userInfo.Call equals callInfo.ID into calls
				  from call in calls.DefaultIfEmpty()
				  join degreeInfo in DbContext.DegreeMaster.AsNoTracking()
				       on userInfo.Degree equals degreeInfo.ID into degrees
				  from degree in degrees.DefaultIfEmpty()
				  join countryInfo in DbContext.LocationMaster.AsNoTracking().Where(x => x.Level == ConstValues.LocationLevel.国家)
				    on userInfo.Country equals countryInfo.ID into countrys
				  from country in countrys.DefaultIfEmpty()
				  select new
				  {
					  ID = userInfo.ID,
					  UserName = userInfo.UserName,
					  FamilyName = userInfo.FamilyName,
					  FirstName = userInfo.FirstName,
					  FullName = userInfo.FullName,
					  Gender = userInfo.Gender,
					  Mail = userInfo.Mail,
					  Birthday = userInfo.Birthday,
					  Affiliation = userInfo.Affiliation,
					  Title = call.CallName,
					  TitleEn = call.CallNameEn,
					  Degree = degree.DegreeName,
					  DegreeEn = degree.DegreeNameEn,
					  Career = userInfo.Career,
					  Telephone = userInfo.Telephone,
					  Mobile = userInfo.Mobile,
					  Country = country.Name,
					  CountryEn = country.NameEn,
					  State = userInfo.StateStr,
					  City = userInfo.CityStr,
					  Address = userInfo.Address,
					  ZipCode = userInfo.ZipCode,
					  OcisCode = userInfo.OcisCode,
					  Department = userInfo.Department,
					  LockTime = userInfo.LockTime,
					  PasswordFailed = userInfo.PasswordFailed,
					  IsLocked = userInfo.IsLocked,
					  Status = userInfo.Status,
					  Sort = userInfo.Sort,
					  Remark = userInfo.Remark,
					  Creator = userInfo.Creator,
					  CreateIP = userInfo.CreateIP,
					  CreateDate = userInfo.CreateDate,
				  };

			if (!string.IsNullOrWhiteSpace(model.SelName))
			{
				sql = sql.Where(x => x.FullName.Contains(model.SelName) ||
					(model.SelName.Contains(x.FirstName) &&
					model.SelName.Contains(x.FamilyName)));
			}
			if (!string.IsNullOrWhiteSpace(model.SelMail))
			{
				sql = sql.Where(x => x.Mail.Contains(model.SelMail));
			}

			int total = await sql.CountAsync();

			if (!string.IsNullOrEmpty(sort))
			{
				sql = sql.OrderBy(sort + ConstValues.chrSpace + order).Skip(skip).Take(take);
			}
			else
			{
				sql = sql.OrderBy(x => x.Sort).ThenByDescending(x => x.CreateDate).ThenBy(x => x.UserName).Skip(skip).Take(take);
			}

			var sqlResult = await sql.ToListAsync();

			var result = sqlResult.Select(x => new
			{
				ID = x.ID,
				UserName = x.UserName,
				FamilyName = x.FamilyName,
				FirstName = x.FirstName,
				FullName = x.FullName,
				Gender = x.Gender ? Resources.Male : Resources.Female,
				Mail = x.Mail,
				Birthday = x.Birthday == null ? string.Empty :
						(Request.Cookies["_culture"].Value == ConstValues.Language.Cn ?
						x.Birthday.Value.ToString("yyyy-MM-dd") :
						x.Birthday.Value.ToString("MM/dd/yyyy")),
				Affiliation = x.Affiliation,
				Title = Request.Cookies["_culture"].Value == ConstValues.Language.Cn ? x.Title : x.TitleEn,
				Degree = Request.Cookies["_culture"].Value == ConstValues.Language.Cn ? x.Degree : x.DegreeEn,
				Career = Utility.GetNameFromIdList(x.Career, "career", Request.Cookies["_culture"].Value),
				Careerlist = x.Career.Split(ConstValues.chrSemicolon),
				Telephone = x.Telephone,
				Mobile = x.Mobile,
				City = x.City,
				State = x.State,
				Country = Request.Cookies["_culture"].Value == ConstValues.Language.Cn ? x.Country : x.CountryEn,
				Address = x.Address,
				ZipCode = x.ZipCode,
				OcisCode = Utility.GetNameFromIdList(x.OcisCode, "ocis"),
				OcisCodelist = x.OcisCode.Split(ConstValues.chrSemicolon),
				Department = x.Department,
				LockTime = x.LockTime,
				IsLocked = x.IsLocked ? Resources.Yes : Resources.No,
				PasswordFailed = x.PasswordFailed,
				Status = x.Status,
				Sort = x.Sort,
				Remark = x.Remark,
				Creator = x.Creator,
				CreateIP = x.CreateIP,
				CreateDate = Request.Cookies["_culture"].Value == ConstValues.Language.Cn ?
					x.CreateDate.Value.ToString("yyyy-MM-dd") :
					x.CreateDate.Value.ToString("MM/dd/yyyy")
			});

			return JsonCamelCase(new
			{
				Total = total,
				Rows = result,
			},
			JsonRequestBehavior.AllowGet);
		}

		public async Task<JsonCamelCaseResult> GetAddData(ConferenceUserMasterModel model)
		{
			var sql = DbContext.SysUserMaster.AsNoTracking().Where(x => x.Status == ConstValues.Status.正常);
			if (!string.IsNullOrWhiteSpace(model.SelAddMail))
			{
				sql = sql.Where(x => x.Mail.Contains(model.SelAddMail));
			}
			if (!string.IsNullOrWhiteSpace(model.SelAddName))
			{
				sql = sql.Where(x => x.UserName.Contains(model.SelAddName));
			}
			if (string.IsNullOrWhiteSpace(model.SelAddMail) && string.IsNullOrWhiteSpace(model.SelAddName))
			{
				sql = sql.Where(x => x.Mail.Contains(model.SelAddMail) && x.UserName.Contains(model.SelAddName));
			}
			int total = await sql.CountAsync();
			sql = sql.OrderBy(x => x.CreateDate);

			var sqlResult = await sql.ToListAsync();
			var result = sqlResult.Select(x => new
			{
				ID = x.ID,
				UserName = x.UserName,
				Mail = x.Mail,
				GroupName = DbContext.ConferenceUserGroupMaster.AsNoTracking().FirstOrDefault(y => y.ID == x.ID)?.UserGroupName,
				RoleName = DbContext.ConferenceRoleMaster.AsNoTracking().FirstOrDefault(y => y.ID == x.ID)?.RoleName,
			});

			return JsonCamelCase(new
			{
				Total = total,
				Rows = result,
			},
			JsonRequestBehavior.AllowGet);
		}

		[Route("CreateRoleAndGroup/{ConferenceId}")]
		public async Task<JsonResult> CreateRoleAndGroup(ConferenceUserMasterModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var ids = model.AllId.Split(ConstValues.chrAnd);
			if (!string.IsNullOrEmpty(model.groupList))
			{
				for (int index = 0; index < ids.Length; index++)
				{
					string tmp = ids[index];
					var result = await DbContext.ConferenceUserAndGroupRelation
							.FirstOrDefaultAsync(x => x.UserId == tmp &&
								x.UserGroupId == model.groupList &&
								x.ConferenceId == model.ConferenceId);

					if (result == null)
					{
						var conferenceUserAndGroupRelation = new ConferenceUserAndGroupRelation
						{
							ID = Utility.GetTableId(ConstValues.TableName.ConferenceUserAndGroupRelation),
							ConferenceId = model.ConferenceId,
							UserGroupId = model.groupList,
							UserId = tmp,
							Status = ConstValues.Status.正常,
							Sort = ConstValues.DefaultSort,
							Remark = string.Empty,
							Creator = LoginUser.UserName,
							CreateIP = LoginUser.IP,
							CreateDate = DateTime.Now
						};
						DbContext.ConferenceUserAndGroupRelation.Add(conferenceUserAndGroupRelation);
					}
				}
			}
			if (!string.IsNullOrEmpty(model.roleList))
			{
				for (int index = 0; index < ids.Length; index++)
				{
					string tmp = ids[index];
					var result = await DbContext.ConferenceUserAndRoleRelation
						.FirstOrDefaultAsync(x => x.UserId == tmp &&
							x.RoleId == model.roleList &&
							x.ConferenceId == model.ConferenceId);

					if (result == null)
					{
						var conferenceUserAndRoleRelation = new ConferenceUserAndRoleRelation
						{
							ID = Utility.GetTableId(ConstValues.TableName.ConferenceUserAndRoleRelation),
							ConferenceId = model.ConferenceId,
							RoleId = model.roleList,
							UserId = tmp,
							Status = ConstValues.Status.正常,
							Sort = ConstValues.DefaultSort,
							Remark = string.Empty,
							Creator = LoginUser.UserName,
							CreateIP = LoginUser.IP,
							CreateDate = DateTime.Now
						};
						DbContext.ConferenceUserAndRoleRelation.Add(conferenceUserAndRoleRelation);
					}
				}
			}

			await DbContext.SaveChangesAsync();

			return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessSubmit),
					JsonRequestBehavior.AllowGet);
		}

		public async Task<JsonCamelCaseResult> GetActionData(ConferenceUserMasterModel model)
		{
			var sql = from user in DbContext.ConferenceUserAndRoleRelation.AsNoTracking()
					.Where(x => x.Status == ConstValues.Status.正常 && x.UserId == model.UserId && x.ConferenceId == model.ConferenceId)
				join actInfo in DbContext.ConferenceRoleAndActionRelation.AsNoTracking()
					.Where(x => x.Status == ConstValues.Status.正常)
				on user.RoleId equals actInfo.RoleId into userInfos
				from userInfo in userInfos.DefaultIfEmpty()
				orderby user.Sort ascending, user.UpdateDate descending
				select new
				{
					ID = user.ID,
					UserId = user.UserId,
					RoleId = user.RoleId,
					ActionId = userInfo.ActionId,
				};

			var sqlResult = await sql.ToListAsync();
			var result = sqlResult.Select(x => new
			{
				ID = x.ID,
				RoleName = DbContext.ConferenceRoleMaster.AsNoTracking().FirstOrDefault(y => y.ID == x.RoleId)?.RoleName,
				UserName = DbContext.SysUserMaster.AsNoTracking().FirstOrDefault(y => y.ID == x.UserId)?.UserName,
				ActionName = DbContext.ConferenceActionMaster.AsNoTracking().FirstOrDefault(y => y.ID == x.ActionId)?.ActionName,
			})
			.OrderBy(x => x.RoleName).ToList();

			return JsonCamelCase(new
			{
				Rows = result,
			},
			JsonRequestBehavior.AllowGet);
		}

		public async Task<JsonCamelCaseResult> GetAction(ConferenceUserMasterModel model)
		{
			var result = await DbContext.ConferenceRoleMaster.AsNoTracking()
					.Where(x => x.Status == ConstValues.Status.正常 && x.ConferenceId == model.ConferenceId)
					.OrderBy(x => x.Sort)
					.ThenBy(x => x.RoleName)
					.Select(x => new
					{
						Id = x.ID,
						ActionName = x.RoleName
					})
					.ToListAsync();

			return JsonCamelCase(result, JsonRequestBehavior.AllowGet);
		}

		[Route("CreateAction/{ConferenceId}")]
		public async Task<JsonResult> CreateAction(ConferenceUserMasterModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var result = await DbContext.ConferenceUserAndRoleRelation
				.FirstOrDefaultAsync(x => x.UserId == model.UserId &&
					x.RoleId == model.RoleId &&
					x.ConferenceId == model.ConferenceId);

			if (result != null)
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(
						string.Format(Resources.MsgRecordExist, Resources.Name)),
						JsonRequestBehavior.AllowGet);
			}

			var conferenceRoleAndActionRelation = new ConferenceUserAndRoleRelation
			{
				ID = Utility.GetTableId(ConstValues.TableName.ConferenceUserAndRoleRelation),
				ConferenceId = model.ConferenceId,
				RoleId = model.RoleId,
				UserId = model.UserId,
				Status = ConstValues.Status.正常,
				Sort = ConstValues.DefaultSort,
				Remark = string.Empty,
				Creator = LoginUser.UserName,
				CreateIP = LoginUser.IP,
				CreateDate = DateTime.Now
			};

			DbContext.ConferenceUserAndRoleRelation.Add(conferenceRoleAndActionRelation);
			await DbContext.SaveChangesAsync();

			return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessSubmit),
					JsonRequestBehavior.AllowGet);
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		[Route("DeleteAction/{ConferenceId}")]
		public async Task<JsonResult> DeleteAction(ConferenceUserMasterModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var result = await DbContext.ConferenceUserAndRoleRelation
					.FirstOrDefaultAsync(x => x.ID == model.Id);

			if (result == null)
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgRecordNotExist),
						JsonRequestBehavior.AllowGet);
			}

			DbContext.ConferenceUserAndRoleRelation.Remove(result);
			await DbContext.SaveChangesAsync();

			return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessDelete),
					JsonRequestBehavior.AllowGet);
		}

		public async Task<JsonCamelCaseResult> GetGroupData(ConferenceUserMasterModel model)
		{
			var sql = from user in DbContext.ConferenceUserAndGroupRelation.AsNoTracking()
					.Where(x => x.Status == ConstValues.Status.正常 && x.UserId == model.userIdGro && x.ConferenceId == model.ConferenceId)
				join rolInfo in DbContext.ConferenceGroupAndRoleRelation.AsNoTracking()
					.Where(x => x.Status == ConstValues.Status.正常)
				on user.UserGroupId equals rolInfo.UserGroupId into rolInfos
				from rolInfo in rolInfos.DefaultIfEmpty()
				join actInfo in DbContext.ConferenceRoleAndActionRelation.AsNoTracking()
					.Where(x => x.Status == ConstValues.Status.正常)
				on rolInfo.RoleId equals actInfo.RoleId into actInfos
				from actInfo in actInfos.DefaultIfEmpty()
				orderby user.Sort ascending, user.UpdateDate descending
				select new
				{
					ID = user.ID,
					UserId = user.UserId,
					RoleId = rolInfo.RoleId,
					ActionId = actInfo.ActionId,
					UserGroupId = user.UserGroupId
				};

			var sqlResult = await sql.ToListAsync();
			var result = sqlResult.Select(x => new
			{
				ID = x.ID,
				GroupName = DbContext.ConferenceUserGroupMaster.AsNoTracking().FirstOrDefault(y => y.ID == x.UserGroupId)?.UserGroupName,
				UserName = DbContext.SysUserMaster.AsNoTracking().FirstOrDefault(y => y.ID == x.UserId)?.UserName,
				RoleName = DbContext.ConferenceRoleMaster.AsNoTracking().FirstOrDefault(y => y.ID == x.RoleId)?.RoleName,
				ActionName = DbContext.ConferenceActionMaster.AsNoTracking().FirstOrDefault(y => y.ID == x.ActionId)?.ActionName,
			})
			.OrderBy(x => x.GroupName).ToList();

			return JsonCamelCase(new
			{
				Rows = result,
			},
			JsonRequestBehavior.AllowGet);
		}

		public async Task<JsonCamelCaseResult> GetGroup(ConferenceUserMasterModel model)
		{
			var result = await DbContext.ConferenceUserGroupMaster.AsNoTracking()
					.Where(x => x.Status == ConstValues.Status.正常 && x.ConferenceId == model.ConferenceId)
					.OrderBy(x => x.Sort)
					.ThenBy(x => x.UserGroupName)
					.Select(x => new
					{
						Id = x.ID,
						ActionName = x.UserGroupName
					})
					.ToListAsync();

			return JsonCamelCase(result, JsonRequestBehavior.AllowGet);
		}

		[Route("CreateGroup/{ConferenceId}")]
		public async Task<JsonResult> CreateGroup(ConferenceUserMasterModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var result = await DbContext.ConferenceUserAndGroupRelation
					.FirstOrDefaultAsync(x => x.UserId == model.userIdGro &&
						x.UserGroupId == model.GroupId &&
						x.ConferenceId == model.conferenceIdGro);

			if (result != null)
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(
						string.Format(Resources.MsgRecordExist, Resources.Name)),
						JsonRequestBehavior.AllowGet);
			}

			var conferenceUserAndGroupRelation = new ConferenceUserAndGroupRelation
			{
				ID = Utility.GetTableId(ConstValues.TableName.ConferenceUserAndGroupRelation),
				ConferenceId = model.conferenceIdGro,
				UserGroupId = model.GroupId,
				UserId = model.userIdGro,
				Status = ConstValues.Status.正常,
				Sort = ConstValues.DefaultSort,
				Remark = string.Empty,
				Creator = LoginUser.UserName,
				CreateIP = LoginUser.IP,
				CreateDate = DateTime.Now
			};

			DbContext.ConferenceUserAndGroupRelation.Add(conferenceUserAndGroupRelation);
			await DbContext.SaveChangesAsync();

			return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessSubmit),
					JsonRequestBehavior.AllowGet);
		}

		[HttpPost]
		[ValidateAntiForgeryToken]
		[Route("DeleteGroup/{ConferenceId}")]
		public async Task<JsonResult> DeleteGroup(ConferenceUserMasterModel model)
		{
			string controller = RouteData.Values["controller"].ToString();
			string actionName = RouteData.Values["action"].ToString();
			Utility.InsertLog(LoginUser, Request.Url.ToString(), controller, actionName, "Index", model.ConferenceId);

			var result = await DbContext.ConferenceUserAndGroupRelation
					.FirstOrDefaultAsync(x => x.ID == model.Id);

			if (result == null)
			{
				return JsonCamelCase(Utility.CreateFailJsonResult(Resources.MsgRecordNotExist),
						JsonRequestBehavior.AllowGet);
			}

			DbContext.ConferenceUserAndGroupRelation.Remove(result);
			await DbContext.SaveChangesAsync();

			return JsonCamelCase(Utility.CreateSuccessJsonResult(Resources.SuccessDelete),
					JsonRequestBehavior.AllowGet);
		}
	}
}